page	80,128
title	CMPS.ASM	1/10/85	bjs

include		GENERAL.EQU
include		PLANET.EQU

SHIP_TO_SHIP_RANGE	EQU	16
SHIP_TO_TORP_RANGE	EQU	8
TORP_TO_TORP_RANGE	EQU	6

BOUNCE_FACTOR		EQU	2

PHOTON_DAMAGE		EQU	4
PLANET_DAMAGE		EQU	2

PUBLIC	Colide

EXTRN	Scork:near
EXTRN	Score:near
EXTRN	Xor_Torp:near

EXTRN	PLANET_ENABLE:byte

EXTRN	EFLG:word
EXTRN	UFLG:word
EXTRN	XDIS:word
EXTRN	YDIS:word
EXTRN	XDISL:word
EXTRN	YDISL:word
EXTRN	XVEL:word
EXTRN	YVEL:word
EXTRN	XVELL:word
EXTRN	YVELL:word
EXTRN	SHLDS:word

space_data	segment	public	'space_data'

CMP_RANGE	DW	0
LAST_OBJ	DW	0

space_data	ends

space_code	segment	public	'space_code'

PAGE
;--- MODULE:	Colide		--------------------------------
; Entry
;	NONE
; Exit
;	NONE
; Affects
;	Register	ax,si,di
;			SHLDS,SCRW,UFLG,EFLG
; Function
;	1. Collision detection between objects.
;--- Revision History
;	12/15/84	bjs
;---------------------------------------------------------------
	ASSUME	CS:space_code,DS:space_data,ES:Nothing

Colide	proc	near
	
	mov  	CMP_RANGE,SHIP_TO_SHIP_RANGE	; range between ships
	mov	di,ENTOBJ			; ent vs.
	mov	si,KLNOBJ			; kln
	call	cmpare				; hit ?
	jb	col010				; yes
	jmp	col190				; no

col010:
	mov	ax,XVELL+ENTOBJ			; get x velocities
	mov	bx,XVEL+ENTOBJ
	mov	cx,XVELL+KLNOBJ
	mov	dx,XVEL+KLNOBJ
	sar	bx,1				; not perfect elastic collision
	rcr	ax,1
	sar	dx,1
	rcr	cx,1
	mov	XVELL+ENTOBJ,cx			; swap velovities
	mov	XVEL+ENTOBJ,dx
	mov	XVELL+KLNOBJ,ax
	mov	XVEL+KLNOBJ,bx

	mov	ax,YVELL+ENTOBJ			; get y velocities
	mov	bx,YVEL+ENTOBJ
	mov	cx,YVELL+KLNOBJ
	mov	dx,YVEL+KLNOBJ
	sar	bx,1				; not perfect elastic collision
	rcr	ax,1
	sar	dx,1
	rcr	cx,1
	mov	YVELL+ENTOBJ,cx			; swap velovities
	mov	YVEL+ENTOBJ,dx
	mov	YVELL+KLNOBJ,ax
	mov	YVEL+KLNOBJ,bx

	mov	si,XDIS+ENTOBJ			; get x position
	mov	di,XDIS+KLNOBJ
	cmp	di,si
	js	col040
	sub	si,BOUNCE_FACTOR
	jns	col020
	add	si,MAX_X_AXIS
col020:
	add	di,BOUNCE_FACTOR
	cmp	di,MAX_X_AXIS
	js	col030
	sub	di,MAX_X_AXIS
col030:
	jmp	col060
col040:
	sub	di,BOUNCE_FACTOR
	jns	col050
	add	di,MAX_X_AXIS
col050:
	add	si,BOUNCE_FACTOR
	cmp	si,MAX_X_AXIS
	js	col060
	sub	si,MAX_X_AXIS
col060:
	mov	XDIS+ENTOBJ,si
	mov	XDIS+KLNOBJ,di

	mov	si,YDIS+ENTOBJ			; get y position
	mov	di,YDIS+KLNOBJ
	cmp	di,si
	js	col100
	sub	si,BOUNCE_FACTOR
	jns	col080
	add	si,MAX_Y_AXIS
col080:
	add	di,BOUNCE_FACTOR
	cmp	di,MAX_Y_AXIS
	js	col090
	sub	di,MAX_Y_AXIS
col090:
	jmp	col120
col100:
	sub	di,BOUNCE_FACTOR
	jns	col110
	add	di,MAX_Y_AXIS
col110:
	add	si,BOUNCE_FACTOR
	cmp	si,MAX_Y_AXIS
	js	col120
	sub	si,MAX_Y_AXIS
col120:
	mov	YDIS+ENTOBJ,si
	mov	YDIS+KLNOBJ,di

	or	byte ptr UFLG+ENTOBJ,BIT0	; flag ent for update
	or	byte ptr UFLG+KLNOBJ,BIT0	; flag kln for update

col190:
	mov	di,ENTOBJ			; ent vs.
	mov	si,KLNOBJ			; kln torps
	mov	LAST_OBJ,ENDOBJ
	mov	CMP_RANGE,SHIP_TO_TORP_RANGE
	call	hits
	mov	di,ENTOBJ			; ent vs.
	mov	si,ENTOBJ			; ent torps
	mov	LAST_OBJ,KLNOBJ
	mov	CMP_RANGE,SHIP_TO_TORP_RANGE
	call	hits
	mov	di,KLNOBJ			; kln vs.
	mov	si,ENTOBJ			; ent torps
	mov	LAST_OBJ,KLNOBJ
	mov	CMP_RANGE,SHIP_TO_TORP_RANGE
	call	hits
	mov	di,KLNOBJ			; kln vs.
	mov	si,KLNOBJ			; kln torps
	mov	LAST_OBJ,ENDOBJ
	mov	CMP_RANGE,SHIP_TO_TORP_RANGE
	call	hits
col200:
	mov	CMP_RANGE,TORP_TO_TORP_RANGE	; torp to torp range
	mov	LAST_OBJ,ENDOBJ
	mov	di,ENTOBJ			; ent torps vs. kln torps
col220:
	inc	di
	inc	di
	cmp	di,KLNOBJ			; all of ent torps ?
	jnb	col400				; yes
	mov	si,KLNOBJ			; kln torps
	call	hits
	jmp	col220
col400:
	test	PLANET_ENABLE,BIT0		; PLANET active ?
	je	col3000				; yes
	mov	si,ENTOBJ-2
col600:
	inc	si
	inc	si
	cmp	si,ENDOBJ			; done ?
	jnb	col3000				; yes
	test	byte ptr EFLG[si],0FFH		; object active
	je	col600				; no
	js	col600				; no
	mov	ax,XDIS[si]			; delta x
	sub	ax,PLANET_X			; PLANET position
	jns	col700
	neg	ax
col700:
	cmp	ax,PLANET_RANGE			; x in range ?
	jnb	col600				; no
	mov	ax,YDIS[si]			; try ent delta y
	sub	ax,PLANET_Y			; PLANET position
	jns	col800
	neg	ax
col800:
	cmp	ax,PLANET_RANGE			; y in range ?
	jnb	col600				; no
	cmp	si,ENTOBJ			; enterprise ?
	jne	col900
	sub	byte ptr SHLDS+ENTOBJ,PLANET_DAMAGE	; do damage to enterprise
	jmp	col600

col900:
	cmp	si,KLNOBJ			; klingon ?
	jne	col1000
	sub	byte ptr SHLDS+KLNOBJ,PLANET_DAMAGE	; do damage to klingon
	jmp	col600

col1000:
	call	Xor_Torp			; erase torp
	cli
	mov	byte ptr UFLG[si],0
	mov	byte ptr EFLG[si],0FFH
	sti
	jmp	col600

col3000:
	ret

Colide	endp

PAGE
;--- MODULE:	hits		--------------------------------
; Entry
;	si = torp scaned to LAST_OBJ
;	di = ship or torp to test against
;	LAST_OBJ = LAST TORP+2
;	CMP_RANGE = range for colision
; Exit
;	NONE
; Affects
;	Register	ax,bx,cx,dx,si,di,bp,es
;			UFLG,EFLG
; function
;	1. Test for hits
;--- Revision History
;	12/15/84	bjs
;---------------------------------------------------------------
	ASSUME	CS:space_code,DS:space_data,ES:Nothing

hits	proc	near

	sti
	inc	si
	inc	si
	cmp	si,LAST_OBJ			; done ?
	jnb	hts600				; yes
	call	cmpare				; a collision ?
	jnb	hits				; no
	push	di				; save di
	call	Xor_Torp			; erase torp 
	cli
	mov	byte ptr UFLG[si],0		; stop updates
	mov	byte ptr EFLG[si],0FFH		; flag exploding
	sti
	pop	di
	cmp	di,ENTOBJ			; is this ent ?
	jne	hts400				; no
	sub	byte ptr SHLDS+ENTOBJ,PHOTON_DAMAGE
	jmp	hits
hts400:
	cmp	di,KLNOBJ			; is it the kln ?
	jne	hts500				; no
	sub	byte ptr SHLDS+KLNOBJ,PHOTON_DAMAGE
	jmp	hits
hts500:
	push	di
	mov	si,di
	call	Xor_Torp			; erase other torp
	pop	di
	cli
	mov	byte ptr UFLG[di],0		; explode other torp too
	mov	byte ptr EFLG[di],0FFH
	sti
hts600:
	ret

hits	endp

PAGE
;--- MODULE:	cmpare		--------------------------------
; Entry
;	CMP_RANGE = min distance
;	si = obj 1
;	di = obj 2
; Exit
;	carry=0 no collision
; Affects
;	Register	ax,cx
; function
;	1. Compare for collision
;--- Revision History
;	12/15/84	bjs
;---------------------------------------------------------------
	ASSUME	CS:space_code,DS:space_data,ES:Nothing

cmpare	proc	near

	test	byte ptr EFLG[di],0FFH		; obj active ?
	je	cmp600				; no - exit carry=1
	js	cmp600				; no - exploding
	test	byte ptr EFLG[si],0FFH		; obj b active
	je	cmp600				; no
	js	cmp600				; no
	mov	ax,YDIS[di]
	sub	ax,YDIS[si]			; gen y delta
	jns	cmp100				; neq. ?
	neg	ax				; complement
cmp100:
	mov	cx,CMP_RANGE
	cmp	ax,cx				; hit ?
	jnb	cmp600				; no - exit
	mov	ax,XDIS[di]
	sub	ax,XDIS[si]
	jns	cmp200				; plus
	neg	ax				; complement
cmp200:
	cmp	ax,cx				; hit ?
cmp600:
	ret

cmpare	endp

space_code	ends
	end

